package de.gwtprime.client.login;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

import de.gwtprime.client.ClientFactory;
import de.gwtprime.client.util.GWTUtils;
import de.gwtprime.client.viewsStatic.LoadingIndictator;
import de.gwtprime.client.widgets.helper.InfoPopup;
import de.gwtprime.shared.requestFactory.User2Proxy;
import de.gwtprime.shared.requestFactory.request.User2Request;
import de.gwtprime.shared.util.AppUtilsShared;
import de.gwtprime.shared.util.LoginHelper;

public class RegisterContainer extends PopupPanel {

	private static RegisterContainer2UiBinder uiBinder = GWT
			.create(RegisterContainer2UiBinder.class);

	interface RegisterContainer2UiBinder extends
			UiBinder<Widget, RegisterContainer> {
	}
	
	@UiField TextBox nameInput;
	@UiField Button sendRegistrationBtn;
	@UiField Button cancelRegistrationBtn;
	@UiField PasswordTextBox passwordInput;
	@UiField PasswordTextBox passwordInputRepeat;
	
	@UiField Label nameLbl;
	@UiField Label passwordLbl;
	@UiField Label passwordRepeatLbl;
	
	@UiField SimplePanel loadingIndicator;
	
	private ClientFactory clientFactory;

	public RegisterContainer(final ClientFactory clientFactory) {
		super(true, true);
		this.clientFactory = clientFactory;
		setGlassEnabled(true);
		setWidget(uiBinder.createAndBindUi(this));
		
		sendRegistrationBtn.setText(GWTUtils.I18n.registrationSend());
		cancelRegistrationBtn.setText(GWTUtils.I18n.registrationCancel());
		
		nameInput.getElement().setAttribute("placeholder", GWTUtils.I18n.emailInputPlaceholder());
		passwordInput.getElement().setAttribute("placeholder", GWTUtils.I18n.passwordInputPlaceholder());
		passwordInputRepeat.getElement().setAttribute("placeholder", "Passwort");
		
		
		nameLbl.setText(GWTUtils.I18n.registrationNameLbl());
		passwordLbl.setText(GWTUtils.I18n.registrationPasswordLbl());
		passwordRepeatLbl.setText(GWTUtils.I18n.registrationPasswordRepeatLbl());
		
		loadingIndicator.add(new LoadingIndictator(false));
		loadingIndicator.addStyleName("invisible");
		
		Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand () {
	        public void execute () {
	        	nameInput.setFocus(true);
	        }
	    });
		
		sendRegistrationBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				register();
			}
		});
		
		nameInput.addKeyDownHandler(new RegisterHandler());
		passwordInput.addKeyDownHandler(new RegisterHandler());
		passwordInputRepeat.addKeyDownHandler(new RegisterHandler());
	}
	
	@UiHandler("cancelRegistrationBtn")
	public void closePopup(ClickEvent e){
		hide();
	}
	
	private void enableRegisterUI(){
		nameInput.setEnabled(true);
		sendRegistrationBtn.setEnabled(true);
		cancelRegistrationBtn.setEnabled(true);
		passwordInput.setEnabled(true);
		passwordInputRepeat.setEnabled(true);
		
		loadingIndicator.addStyleName("invisible");
	}
	
	private void disableRegisterUI(){
		
		nameInput.setEnabled(false);
		sendRegistrationBtn.setEnabled(false);
		cancelRegistrationBtn.setEnabled(false);
		passwordInput.setEnabled(false);
		passwordInputRepeat.setEnabled(false);
		
		loadingIndicator.removeStyleName("invisible");
	}
	
	/**
	 * 
	 * @param clientFactory
	 */
	private void register() {
		// Disable the register button to prevent multiple registrations
		disableRegisterUI();
		
		final String password = passwordInput.getText();
		String pass2 = passwordInputRepeat.getText();
		String userName = nameInput.getText();
		
		if(!password.equals(pass2)){
			new InfoPopup(GWTUtils.I18n.passwordsDoNotMatch()).center();
			enableRegisterUI();
			return;
		}
		
		if(!LoginHelper.isValidEmail(userName)){
			new InfoPopup(GWTUtils.I18n.registrationEmailInvalidMsg()).center();
			enableRegisterUI();
			return;
		}
		
		if(!LoginHelper.isUserNameValid(userName)){
			new InfoPopup(GWTUtils.I18n.userNameInvalidMsg(AppUtilsShared.minimumUserNameLength)).center();
			enableRegisterUI();
			return;
		}
		if(!LoginHelper.isPasswordValid(password)){
			new InfoPopup(GWTUtils.I18n.passwordInvalidMsg(AppUtilsShared.minimumPasswordLength)).center();
			enableRegisterUI();
			return;
		}
		
		sendRegistrationBtn.setEnabled(false);
		User2Request request = clientFactory.getRequestFactory().userRequest();
		
		request.findUserByEmail(nameInput.getText()).fire(new Receiver<User2Proxy>() {

			@Override
			public void onSuccess(User2Proxy response) {
				
				if(response!=null){
					new InfoPopup(GWTUtils.I18n.emailAlreadyRegistered()).center();
					enableRegisterUI();
				}
				
				else{
					clientFactory.getNotificationCenter().showMessage(GWTUtils.I18n.registratrionSuccessfulNotification());
					
					hide();
					new InfoPopup(GWTUtils.I18n.registratrionSuccessful()).center();
					
					completeRegistration(password);
				}
			}
			
			@Override
			public void onFailure(ServerFailure error) {
				enableRegisterUI();
				new InfoPopup("Registrierung ist fehlgeschlagen").center();
			}
		});
	}
	
	
	/**
	 * 
	 * @param clientFactory
	 * @param password
	 */
	private void completeRegistration(String password) {
		
		final User2Request request = clientFactory.getRequestFactory().userRequest();
		User2Proxy user = request.create(User2Proxy.class);
		user.setPass1(password);
		
		user.setEmail(nameInput.getText());
		
		
		request.persistNewUser().using(user).fire(new Receiver<Long>() {
			@Override
			public void onSuccess(Long response) {
			}
		});
	}
	
	class RegisterHandler implements KeyDownHandler{
		@Override
		public void onKeyDown(KeyDownEvent event) {
			if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
				register();
			}
		}
	}
}
